package com.spzx.service.impl;

import com.spzx.cart.api.domain.CartInfo;
import com.spzx.common.core.constant.SecurityConstants;
import com.spzx.common.core.context.SecurityContextHolder;
import com.spzx.common.core.domain.R;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.product.api.RemoteProductService;
import com.spzx.product.api.domain.ProductSku;
import com.spzx.product.api.domain.SkuPrice;
import com.spzx.service.ICartService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class CartServiceImpl implements ICartService {
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RemoteProductService remoteProductService;

    private String getCartKey(Long userId) {
        //定义key user:cart:userId
        return "user:cart:" + userId;
    }

    @Override
    public void addToCart(Long skuId, Integer skuNum) {
        //获取当前登录用户id
        Long userId = SecurityContextHolder.getUserId();

        //构建“用户”购物车hash结构key  user:cart:用户ID
        String cartKey = getCartKey(userId);

        //创建Hash结构绑定操作对象
        BoundHashOperations<String, String, CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);

        int thresHold = 99;
        if (boundHashOperations.hasKey(skuId.toString())) {

            CartInfo cartInfo = boundHashOperations.get(skuId.toString());

            int count = cartInfo.getSkuNum() + skuNum;

            cartInfo.setSkuNum(count > 99 ? thresHold : count);
            cartInfo.setUpdateTime(new Date());
            boundHashOperations.put(skuId.toString(), cartInfo);
        } else {
            Long size = boundHashOperations.size();
            if (++size > 50) {
                throw new ServiceException("购物车不同商品上限不能超过50");
            }

            CartInfo cartInfo = new CartInfo();
            cartInfo.setUserId(userId);
            cartInfo.setSkuId(skuId);
            cartInfo.setCreateTime(new Date());
            R<ProductSku> productSkuResult = remoteProductService.getProductSku(skuId, SecurityConstants.INNER);
            if (R.FAIL == productSkuResult.getCode()) {
                throw new ServiceException(productSkuResult.getMsg());
            }
            ProductSku productSku = productSkuResult.getData();
            cartInfo.setCartPrice(productSku.getSalePrice());
            cartInfo.setSkuPrice(productSku.getSalePrice());
            cartInfo.setSkuNum(1);
            cartInfo.setThumbImg(productSku.getThumbImg());
            cartInfo.setSkuName(productSku.getSkuName());
            cartInfo.setIsChecked(1);

            boundHashOperations.put(skuId.toString(), cartInfo);
        }
    }

    //查询购物车
    @Override
    public List<CartInfo> getCartList() {
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);

        //获取购物车商品集合
        List<CartInfo> cartInfoList = boundHashOperations.values();
         cartInfoList = cartInfoList.stream().sorted(((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime()))).toList();

         if (CollectionUtils.isEmpty(cartInfoList)){
             List<Long> skuIdList = cartInfoList.stream().map(cartInfo -> cartInfo.getSkuId()).toList();
             R<List<SkuPrice>> skuPriceListResult = remoteProductService.getSkuPriceList(skuIdList, SecurityConstants.INNER);
             if (R.FAIL == skuPriceListResult.getCode()){
                 throw new ServiceException(skuPriceListResult.getMsg());
             }
             List<SkuPrice> skuPriceList = skuPriceListResult.getData();
             //转map类型
             Map<Long, BigDecimal> skuIdToSalePriceMap  = skuPriceList.stream().collect(Collectors.toMap(SkuPrice::getSkuId, SkuPrice::getSalePrice));
             cartInfoList.forEach(cartInfo ->
                     {
                         BigDecimal skuPrice = skuIdToSalePriceMap.get(cartInfo.getSkuId());
                         cartInfo.setCartPrice(skuPrice);
                     });
         }
        return cartInfoList;
    }

    //删除购物车商品
    @Override
    public void deleteCart(Long skuId) {
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        boundHashOperations.delete(skuId.toString());
    }

    //更新选中状态
    @Override
    public void checkCart(Long skuId, Integer isChecked) {
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        if (boundHashOperations.hasKey(skuId.toString())){
            CartInfo cartInfo = boundHashOperations.get(skuId.toString()); //取
            cartInfo.setIsChecked(isChecked); //改
            boundHashOperations.put(skuId.toString(),cartInfo);
        }
    }

    //更新购物车商品全部选中状态
    @Override
    public void allCheckCart(Integer isChecked) {
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = boundHashOperations.values();
        if (!CollectionUtils.isEmpty(cartInfoList)){
            for (CartInfo cartInfo : cartInfoList) {
                cartInfo.setIsChecked(isChecked);
                boundHashOperations.put(cartInfo.getSkuId().toString(),cartInfo);
            }
        }
    }

    //清空购物车
    @Override
    public void clearCart() {
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        //获取缓存对象
        redisTemplate.delete(cartKey);
    }

    //查询用户购物车列表中选中商品列表
    @Override
    public List<CartInfo> getCartCheckedList(Long userId) {
        //存放勾选商品
        ArrayList<CartInfo> cartInfoCheckList = new ArrayList<>();
        String cartKey = getCartKey(userId);
        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = boundHashOperations.values();
        for (CartInfo cartInfo : cartInfoList) {
            if (cartInfo.getIsChecked() == 1){
                cartInfoCheckList.add(cartInfo);
            }
        }
        return cartInfoCheckList;
    }

    //更新用户购物车列表价格
    @Override
    public Boolean updateCartPrice(Long userId) {
        String cartKey = getCartKey(userId);
        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = boundHashOperations.values();

        if (!CollectionUtils.isEmpty(cartInfoList)) {
            for (CartInfo cartInfo : cartInfoList) {
                if (cartInfo.getIsChecked().intValue() == 1) {
                    R<SkuPrice> productSkuPriceResult = remoteProductService.getProductSkuPrice(cartInfo.getSkuId(), SecurityConstants.INNER);
                    if (R.FAIL == productSkuPriceResult.getCode()) {
                        throw new ServiceException(productSkuPriceResult.getMsg());
                    }
                    SkuPrice skuPrice = productSkuPriceResult.getData();
                    cartInfo.setCartPrice(skuPrice.getSalePrice());
                    cartInfo.setSkuPrice(skuPrice.getSalePrice());
                    boundHashOperations.put(cartInfo.getSkuId().toString(),cartInfo);
                }
            }
        }
        return true;
    }

    //删除用户购物车列表中选中商品列表
    @Override
    public Boolean deleteCartCheckedList(Long userId) {
        String cartKey = getCartKey(userId);
        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = boundHashOperations.values();
        if (!CollectionUtils.isEmpty(cartInfoList)){
            for (CartInfo cartInfo : cartInfoList) {
                if (cartInfo.getIsChecked().intValue() ==1){
                    boundHashOperations.delete(cartInfo.getSkuId().toString());
                }
            }
        }
        return true;
    }
}
